#ifndef SimpleCapture_h__
#define SimpleCapture_h__

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <conio.h>

#include <midlib2.h>

#ifdef UG_EXPORT_SIMPLE_CAPTURE
#define UGEXPORT __declspec(dllexport)
#else
#define UGEXPORT
#endif

#define NUM_WORKER_THREADS      2 
#define DEFAULT_NUM_FRAMES      1
#define PIXELBITS               16
#define MAX_BADFRAME_TRIES      10

#define MAX_CAMS 2



/**
 *	\brief Modified from the SimpleCapture example provided by Aptina.
 */
class SimpleCapture
{
public:

  /************************************************************************/
  /* PUBLIC STATIC MEMBERS                                                */
  /************************************************************************/ 
    static mi_s32 num_cameras;
    static bool isMidLibInit;
    
    /** 
     * \brief Init all cams, make sure at least nCamsReq 
     * cameras were initialized.
     * \return 0 on success, or greater than 0 on failure.
     */
    UGEXPORT static int initMidLib2(int nCamsReq);

  /************************************************************************/
  /* PUBLIC MEMBERS                                                       */
  /************************************************************************/ 
    mi_camera_t     *pCamera; //=NULL;                     //current camera
    unsigned long   frameSize;                             //size of the frames we want to save
    unsigned char   *pCameraBuff;                          //memory buffer for all the sensor images
    unsigned char   *pGrabframeBuff;                       //grabFrame buffer
    unsigned int    num_frames;// = DEFAULT_NUM_FRAMES;    //number of frames to capture
    unsigned long   nWidth;//  = 0;                        //width of image (taken from command line or set to default below)
    unsigned long   nHeight;// = 0;                        //height of image (taken from command line or set to default below)
    FILE            *imfile;                               //capture file
    unsigned int    frame;
    mi_u32          nSwizzleNeeded;
    mi_string       errorFileName;
    char            imagetypestr[32];

  /************************************************************************/
  /* PUBLIC METHODS                                                       */
  /************************************************************************/ 
    static mi_u32 miDevCallBack(HWND, _mi_camera_t*, mi_u32);

    UGEXPORT SimpleCapture();
    ~SimpleCapture();

	int getWavelength();

    /**
     *	\brief Open the midlib2 transport for the given camera index.
     *	
     *	initMidLib2() must be called prior to calling openTransport(). The
     *	parameter camidx sets is index for the camera that will have its
     *  transport opened. camidx must be less than or equal to the number of 
     *  cameras that were initialized by initMidLib2().
     * 
	 *  The return value is the MI_CAMERA_* error code.
     *	
     *	\param camidx The camera index to open transport for. Must be <= to the number
     *	of cameras that midlib2 found.
     *
     *  \return -1 if initmidlib() was never called before the call to openTransport(), 
     *          -2 if no cameras were found, 
	 *           0 on success, 
     *           otherwise an MI_CAMERA_* error code is returned.
     *  
     */
    int  openTransport(int camidx); 

    /** 
     *  \brief Stop the transport for this SimpleCapture's camera. 
     */
    void stopTransport();

    /**
      *	\brief Returns the size of the image data buffers being used by MidLib2.
      * These buffers contain the image data, and are large enough to contain the
      * entire raw data from a single camera capture.
      */
    unsigned long sensorBufferSize();

    unsigned char* _doCapture();

    void setIniPath(char *path)
    {
        
    }

  /************************************************************************/
  /* PRIVATE members                                                      */
  /************************************************************************/ 
private:

    int m_cameraIdx;         //< this camera's index into gCameras.
    int m_nextFrameIdx;      //< unused.
    int m_camNM;             //< This camera's filter wavelength.
    char *iniFilePath;
    int mallocate();
    void printCameraInfo();
};

/************************************************************************/
/* Begin class ManagedSimpleCapture                                     */
/************************************************************************/


public ref class ManagedSimpleCapture {
    SimpleCapture *native_sc;

public:
    ManagedSimpleCapture() 
        : native_sc(new SimpleCapture()) {}
    ~ManagedSimpleCapture() { delete native_sc; }

    /**
    *	\brief CLR Wrapper function around openTransport
    * 
    *	\param camidx The camera index to open transport for. Must be <= to the number
    *	of cameras that midlib2 found.
    * 
    *  \return 1 on error, 0 on success.
    */
    int managed_OpenTransport(int camidx)
    {
        return native_sc->openTransport(camidx);
    }

    /**
    *	\brief Get the wave
    */
    int managed_GetWavelength()
    {
        return native_sc->getWavelength();
    }

    /**
    *	\brief CLR wrapper around sensorBufferSize().
    */
    unsigned long managed_SensorBufferSize()
    {
        return native_sc->sensorBufferSize();
    }

    void managed_setIniPath(char *pathName)
    {
	   	native_sc->setIniPath(pathName);
    }
    /**
    *	\brief CLR wrapper around stopTransport.
    */
    void managed_StopTransport()
    {
        native_sc->stopTransport();
    }

    /**
    *  \brief CLR wrapper around _doCapture.
    */
    unsigned char* managed_DoCapture()
    {
        return native_sc->_doCapture();
    }

    static int managed_InitMidLib(System::IntPtr hwnd, int nCamsReqd)
    {
        //HWND thisSucks((HWND)(hwnd.ToPointer())); //= hwnd.ToPointer();
        //return SimpleCapture::initMidLib2(thisSucks, nCamsReqd);
        return 0;
    }
};

//static void 
//str_replace(char* strOut, char* strIn, char* oldStr, char* newStr)
//{
//    int total_len = (int)strlen(strIn);
//    char* pChar;
//    int lenBeg;
//
//    pChar= strstr(strIn,oldStr);
//    lenBeg = total_len-(int)strlen(pChar);
//    strncpy(strOut, strIn,lenBeg);
//    strOut[lenBeg] = 0;
//    strcat(strOut,newStr);
//    strcat(strOut,&strIn[lenBeg+strlen(oldStr)]);
//}

#endif // SimpleCapture_h__
